#ifndef WSNIPV4_H_
#define WSNIPV4_H_

/*
 *  @Author Hien Hoang
 *  @Version Nov 26, 2013
 * */
#include "INETDefs.h"

#include "ICMPAccess.h"
#include "IPv4FragBuf.h"
#include "ProtocolMap.h"
#include "QueueBase.h"
#include "IPv4Datagram.h"
#include "ILifecycle.h"
#include "INotifiable.h"

class ARPPacket;
class ICMPMessage;
class IInterfaceTable;
class IPv4Datagram;
class IRoutingTable;
class NotificationBoard;


class WSNIPv4 : public QueueBase, INotifiable {

protected:
    IRoutingTable *rt;
    IInterfaceTable *ift;
    NotificationBoard *nb;
    cGate *queueOutGate;

    // config
    int defaultTimeToLive;
    int defaultMCTimeToLive;

    bool isUp;
    long curFragmentId; // counter, used to assign unique fragmentIds to datagrams
    ProtocolMapping mapping; // Where to send package after decapsulation

    //Statictics
    int numDropped;
    int numSent;
    int numForward;

protected:
    virtual void handlePacketFromLower(IPv4Datagram *datagram, InterfaceEntry *fromIE);
    virtual void handleMessageFromHigher(cPacket *msg);
    virtual void handleARP(ARPPacket *msg);
    virtual void sendToRouting(IPv4Datagram *datagram);
    virtual void sendToUpper(IPv4Datagram *datagram);
    virtual void sendDatagramToOutput(IPv4Datagram *datagram, InterfaceEntry *ie, IPv4Address nextHopAddr);
    virtual void routePacket(IPv4Datagram *datagram, InterfaceEntry *destIE, IPv4Address nextHopAddr);
    virtual IPv4Datagram *encapsulate(cPacket *protocolPacket, IPv4ControlInfo *controlInfo);
    virtual cPacket *decapsulate(IPv4Datagram *datagram);
    virtual void endService(cPacket *msg);
    virtual InterfaceEntry *getSourceInterfaceFrom(cPacket *msg);
    virtual IPv4Datagram *createIPv4Datagram(const char *name);
    virtual void updateNodeDisplay();
    virtual void receiveChangeNotification(int category, const cObject *details);

public:
    WSNIPv4() {}
    virtual void initialize(int stage);
    int numInitStages() const {return 5;}

};

#endif /* WSNIPV4_H_ */
